package study.activiti.l_groupTask02;

import java.io.InputStream;
import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.junit.Test;

/**  
 * @Name: GroupTaskTest
 * @Description: 组任务测试类：使用类设置组任务的候选办理人
 * 说明:
 * 		1）在类中使用delegateTask.addCandidateUser (userId);的方式分配组任务的办理人
 * 		2）通过processEngine.getTaskService().claim (taskId, userId);将组任务分配给个人任务，也叫认领任务，即指定某个人去办理这个任务。
 * 		注意：认领任务的时候，可以是组任务成员中的人，也可以不是组任务成员的人，此时通过Type的类型为participant来指定任务的办理人
 * 		3）addCandidateUser()即向组任务添加成员，deleteCandidateUser()即删除组任务的成员。
 * 		4）在开发中，可以将每一个任务的办理人规定好，例如张三的领导是李四和王五，这样张三提交任务，由李四或者王五去查询组任务
 * 		可以看到对应张三的申请，李四或王五再通过认领任务（claim）的方式，由某个人去完成这个任务。
 * @Author: 李超
 * @Create Date: 2016-12-16
 */
public class GroupTaskTest {
	
	//流程引擎
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine() ;
	
	//部署流程定义、启动流程实例
	@Test
	public void deploymentProcessDefinitionAndStartProcessInstance() {
		//1、部署流程定义
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("groupTask.bpmn") ;
		InputStream inputStreamPng = this.getClass().getResourceAsStream("groupTask.png") ;
		processEngine.getRepositoryService()
					 .createDeployment()
					 .name("组任务-使用类指定任务候选人") 
					 .addInputStream("groupTask.bpmn", inputStreamBpmn)
					 .addInputStream("groupTask.png", inputStreamPng)
					 .deploy() ;
		//2、启动流程实例
		String processDefinitionKey = "groupTask" ;
		ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey) ;
		System.out.println("流程实例启动成功");
		System.out.println("流程实例id:" + processInstance.getId());
		System.out.println("####################################");
	}
	
	//根据候选人查看组任务列表
	@Test
	public void queryGroupTaskByCandidateUser() {
		//组任务候选人
		String candidateUser = "孙悟空" ;
		List<Task> list = processEngine.getTaskService().createTaskQuery().taskCandidateUser(candidateUser).list() ;
		if(list != null && list.size() > 0) {
			for (Task task : list) {
				System.out.println("任务id:" + task.getId());
				System.out.println("任务名称:" + task.getName());
				System.out.println("任务办理人:" + task.getAssignee());
				System.out.println("任务创建时间:" + task.getCreateTime());
				System.out.println("流程实例id:" + task.getProcessInstanceId());
				System.out.println("执行对象id:" + task.getExecutionId());
				System.out.println("#####################################");
			}
		}
	}
	
	//拾取任务：指定组任务的办理人，可以从候选人中指定，也可以任意指定
	@Test
	public void claim() {
		//任务id
		String taskId = "227508" ;
		//组任务候选人
		String candidateUser = "孙悟空" ;
		//指定组任务的办理人
		processEngine.getTaskService().setAssignee(taskId, candidateUser) ;
	}
	
	//查询个人任务
	@Test
	public void queryMyPersonalTask() {
		//任务办理人
		String assignee = "孙悟空" ;
		//根据任务的办理人查询个人任务
		List<Task> list = processEngine.getTaskService().createTaskQuery().taskAssignee(assignee).list() ;
		if(list != null && list.size() > 0) {
			for (Task task : list) {
				System.out.println("任务id:" + task.getId());
				System.out.println("任务名称:" + task.getName());
				System.out.println("任务办理人:" + task.getAssignee());
				System.out.println("任务创建时间:" + task.getCreateTime());
				System.out.println("流程实例id:" + task.getProcessInstanceId());
				System.out.println("执行对象id:" + task.getExecutionId());
				System.out.println("##########################################");
			}
		}
	}
	
	//回退任务：置空任务的办理人，将个人任务回撤到组任务
	@Test
	public void setAssigneeIsNull() {
		//任务id
		String taskId = "227508" ;
		processEngine.getTaskService().setAssignee(taskId, null) ;
	}
	
	//查询组任务的候选人列表
	@Test
	public void queryGroupUsers() {
		//任务id
		String taskId = "227508" ;
		//根据任务id查询组任务候选人
		List<IdentityLink> list = processEngine.getTaskService().getIdentityLinksForTask(taskId) ;
		if(list != null && list.size() > 0) {
			for (IdentityLink identityLink : list) {
				System.out.println("候选人类型:" + identityLink.getType());
				System.out.println("候选人名称:" + identityLink.getUserId());
				System.out.println("候选人任务id:" + identityLink.getTaskId());
				System.out.println("####################################");
			}
		}
	}
	
	//新增组任务候选人
	@Test
	public void addGroupUser() {
		//任务id
		String taskId = "227508" ;
		//新增候选人名称
		String userId = "沙僧" ;
		//新增组任务候选人
		processEngine.getTaskService().addCandidateUser(taskId, userId) ;
	}

	//删除组任务候选人
	@Test
	public void deleteGroupUser() {
		//任务id
		String taskId = "227508" ;
		//待删除的组任务候选人
		String userId = "沙僧" ;
		//删除组任务候选人
		processEngine.getTaskService().deleteCandidateUser(taskId, userId) ;
	}
	
	//办理任务
	@Test
	public void completeTask() {
		//任务id
		String taskId = "227508" ;
		//根据任务id完成任务
		processEngine.getTaskService().complete(taskId) ;
	}
	
	//查询历史任务办理人
	@Test
	public void queryHistoricTaskAssignee() {
		//任务id
		String taskId = "227508" ;
		//根据任务id查询历史，查询出任务办理人
		List<HistoricTaskInstance> list = processEngine.getHistoryService()
													   .createHistoricTaskInstanceQuery()
													   .taskId(taskId)
													   .list() ;
		if(list != null && list.size() > 0) {
			for (HistoricTaskInstance hti : list) {
				System.out.println("任务id:" + taskId);
				System.out.println("任务办理人:" + hti.getAssignee());
			}
		}
	}
	
	//查询历史组任务候选人
	@Test
	public void queryHistoricGroupTaskCandidateUsers() {
		//任务id
		String taskId = "227508" ;
		//根据任务id查询历史任务办理人
		List<HistoricIdentityLink> list = processEngine.getHistoryService()
													   .getHistoricIdentityLinksForTask(taskId) ; //根据任务id查询历史任务办理人
//													   .getHistoricIdentityLinksForProcessInstance(processInstanceId) ; //根据流程实例id查询历史任务办理人
		if(list != null && list.size() > 0) {
			for (HistoricIdentityLink hil : list) {
				System.out.println("任务办理人类型:" + hil.getType());
				System.out.println("任务办理人名称:" + hil.getUserId());
				System.out.println("任务id:" + hil.getTaskId());
				System.out.println("流程实例id:" + hil.getProcessInstanceId());
				System.out.println("######################################");
			}
		}
	}

}
